package com.papper.mng.controller.base;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.papper.common.bean.base.BaseConstRegion;
import com.papper.common.bean.sys.SysAuth;
import com.papper.common.constant.SystemConstants;
import com.papper.common.enums.DataStatusEnum;
import com.papper.common.exception.ServiceException;
import com.papper.common.service.DwzPage;
import com.papper.common.service.base.BaseConstRegionService;
import com.papper.common.utils.tool.DateTool;
import com.papper.common.utils.tool.StringTool;
import com.papper.mng.controller.BaseAction;
import com.papper.mng.domain.DwzResponse;
import com.papper.mng.domain.excel.BaseConstRegionVo;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.util.StringUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @Author:LaJiao
 * @Date:2022-03-29 10:06:49
 * @Description:地区列表
 */
@Controller
@RequestMapping("/base/const/region")
public class BaseConstRegionController extends BaseAction {

    @Autowired
    BaseConstRegionService baseConstRegionService;

    /**
     * 地区列表
     *
     * @return
     */
    @RequestMapping(value = "")
    public String execute(HttpServletRequest _request, Model model) {
        // 字段查询条件
        Map<String, Object> objects = Maps.newHashMap();
        extraParams(objects, _request, BaseConstRegion.class);
        modelParm(objects, model);
        // 分页查询条件
        int pageNum    = StringTool.parseInteger(_request.getParameter("pageNum"), 1);
        int numPerPage = StringTool.parseInteger(_request.getParameter("numPerPage"), SystemConstants.PAGE_LIMIT_16);
        // 数据查询组装
        Example example = buildExample(objects, model, BaseConstRegion.class);
        example.setOrderByClause("region_code asc");
        PageInfo<BaseConstRegion> pageRtn = baseConstRegionService.findPage(pageNum, numPerPage, example);
        model.addAttribute("page", new DwzPage(pageNum, numPerPage, pageRtn.getTotal()));
        model.addAttribute("records", pageRtn.getList());
        return render("base/const/region/index");
    }

    /**
     * 地区列表_新增
     */
    @GetMapping(value = "/add")
    public String add_get(Model model, Long pid) {
        BaseConstRegion constRegion = baseConstRegionService.findById(pid);
        if (constRegion == null) {
            model.addAttribute("pid", 0);
            model.addAttribute("regionName", "顶级配置");
        } else {
            model.addAttribute("pid", pid);
            model.addAttribute("regionName", constRegion.getRegionName());
        }
        return render("base/const/region/add");
    }

    @PostMapping(value = "/add")
    @ResponseBody
    public DwzResponse add_post(HttpServletRequest _request, BaseConstRegion baseConstRegion) {
        try {
            checkVerifyCert(_request);
        } catch (ServiceException e) {
            return new DwzResponse("300", e.getMessage());
        }

        // 添加地区列表
        try {
            baseConstRegion.setDataStatus(DataStatusEnum.OPEN.getCode());
            baseConstRegion.setCreateTime(new Date());
            baseConstRegion.setModifyTime(new Date());
            baseConstRegionService.save(baseConstRegion);
            return new DwzResponse("200", "地区列表添加成功!!!", "closeCurrent");
        } catch (Exception e) {
            e.printStackTrace();
            return new DwzResponse("300", "地区列表添加失败:" + e.getMessage() + "!!!");
        }
    }

    /**
     * 地区列表_更新
     */
    @GetMapping(value = "/edit")
    public String edti_get(Model model, Long id) {
        BaseConstRegion entity = baseConstRegionService.findById(id);
        model.addAttribute("entity", entity);
        return render("base/const/region/edit");
    }

    @PostMapping(value = "/edit")
    @ResponseBody
    public DwzResponse edit_post(HttpServletRequest _request, BaseConstRegion baseConstRegion) {
        try {
            checkVerifyCert(_request);
        } catch (ServiceException e) {
            return new DwzResponse("300", e.getMessage());
        }
        if (baseConstRegion == null || baseConstRegion.getId() == null) {
            return new DwzResponse("300", "参数异常！");
        }
        try {
            baseConstRegion.setModifyTime(new Date());
            baseConstRegionService.update(baseConstRegion);
            return new DwzResponse("200", "地区列表修改成功!!!", "closeCurrent");
        } catch (Exception e) {
            e.printStackTrace();
            return new DwzResponse("300", "地区列表修改失败:" + e.getMessage());
        }
    }

    /**
     * 地区列表_删除
     *
     * @param id
     * @
     */
    @PostMapping(value = "/del")
    @ResponseBody
    public DwzResponse del_post(HttpServletRequest _request, Long id) {
        try {
            checkVerifyCert(_request);
        } catch (ServiceException e) {
            return new DwzResponse("300", e.getMessage());
        }
        if (id == null || id.intValue() <= 0) {
            return new DwzResponse("300", "参数ID为空！");
        }

        BaseConstRegion old = baseConstRegionService.findById(id);

        if (old == null) {
            return new DwzResponse("300", "参数[id]信息异常！");
        }
        try {
            baseConstRegionService.deleteById(id);
            return new DwzResponse("200", "地区列表删除成功!!!");
        } catch (Exception e) {
            e.printStackTrace();
            return new DwzResponse("300", "地区列表删除失败:" + e.getMessage());
        }
    }

    /**
     * 地区列表_详情
     *
     * @return
     */
    @GetMapping(value = "/detail")
    public String detail(HttpServletResponse _response, Model model, Long id) {
        BaseConstRegion baseConstRegion = baseConstRegionService.findById(id);
        model.addAttribute("entity", baseConstRegion);
        return render("base/const/region/detail");
    }

    @RequestMapping(value = "/combox")
    @ResponseBody
    public List<List<String>> combox(HttpServletRequest _request) throws IOException {
        // 字段查询条件
        List<List<String>> rtn      = Lists.newArrayList();
        List<String>       items    = Lists.newArrayList();
        String             parentId = _request.getParameter("parentId");
        if (StringTool.isEmpty(parentId)) {
            items = Lists.newArrayList();
            items.add("");
            items.add("--请选择--");
            rtn.add(items);
            return rtn;
        }
        List<BaseConstRegion> constRegions = baseConstRegionService.findByParent(parentId);
        rtn.add(items);
        if (constRegions == null || constRegions.isEmpty()) {
            items = Lists.newArrayList();
            items.add("");
            items.add("--请选择--");
            rtn.add(items);
        } else {
            items = Lists.newArrayList();
            items.add("");
            items.add("--请选择--");
            rtn.add(items);
            for (BaseConstRegion constRegion : constRegions) {
                items = Lists.newArrayList();
                items.add(constRegion.getRegionCode());
                items.add(constRegion.getRegionName());
                rtn.add(items);
            }
        }
        return rtn;
    }

    /**
     * 地区码_导入
     *
     * @return
     */
    @GetMapping(value = "/import")
    public String import_get() throws IOException {
        return render("base/const/region/import");
    }

    @PostMapping(value = "/import")
    @ResponseBody
    public DwzResponse import_post(HttpServletRequest _request, @RequestParam MultipartFile file) throws IOException {
        try {
            checkSuperCert(_request);
        } catch (ServiceException e) {
            return new DwzResponse("300", e.getMessage());
        }
        if (file == null || file.getSize() <= 0) {
            return new DwzResponse("300", "请上传格式xlsx的文件");
        }

        if (!file.getOriginalFilename().endsWith("xlsx")) {
            return new DwzResponse("300", "请上传格式xlsx的文件");
        }

        List<BaseConstRegion>    addRecords = Lists.newArrayList();
        AtomicReference<Integer> succCount  = new AtomicReference<>(0);
        AtomicReference<Integer> failCount  = new AtomicReference<>(0);
        ZipSecureFile.setMinInflateRatio(-1.0d);
        EasyExcel.read(file.getInputStream(), BaseConstRegionVo.class, new PageReadListener<BaseConstRegionVo>(dataList -> {
            for (BaseConstRegionVo data : dataList) {
                if (StringUtil.isEmpty(data.getProvince()) || StringUtil.isEmpty(data.getName()) || StringUtil.isEmpty(data.getCity()) || StringUtil.isEmpty(data.getArea())) {
                    failCount.getAndSet(failCount.get() + 1);
                    continue;
                }
                String          code     = data.getProvince() + data.getCity() + data.getCity();
                BaseConstRegion dbRegion = baseConstRegionService.findByCode(code);
                if (dbRegion != null) {
                    failCount.getAndSet(failCount.get() + 1);
                    continue;
                }
                BaseConstRegion constRegion = new BaseConstRegion();
                constRegion.setRegionCode(code);
                constRegion.setRegionName(data.getName());
                if ("00".equals(data.getCity()) && "00".equals(data.getArea())) {
                    constRegion.setRegionType("1");
                    constRegion.setParentId("000000");
                } else if (!"00".equals(data.getCity()) && "00".equals(data.getArea())) {
                    constRegion.setRegionType("2");
                    constRegion.setParentId(data.getProvince() + "00" + "00");
                } else if (!"00".equals(data.getCity()) && !"00".equals(data.getArea())) {
                    constRegion.setRegionType("3");
                    constRegion.setParentId(data.getProvince() + data.getCity() + "00");
                }
                constRegion.setDataStatus(DataStatusEnum.OPEN.getCode());
                constRegion.setCreateTime(new Date());
                constRegion.setModifyTime(new Date());
                addRecords.add(constRegion);
                succCount.set(succCount.get() + 1);
            }
        })).sheet().doRead();
        baseConstRegionService.batchInsert(addRecords);
        return new DwzResponse("200", "身份地区数据入库成功:[" + succCount + "] 失败:[" + failCount + "]!!!", "closeCurrent");
    }

    /**
     * 明细导出
     *
     * @return
     */
    @RequestMapping(value = "/excel")
    public void excel(HttpServletRequest _request, HttpServletResponse _response, Model model) throws IOException {
        // 读取数据
        List<List<String>> records  = new ArrayList<>();
        Example            conditon = new Example(SysAuth.class);
        conditon.setOrderByClause("region_code asc");
        int                       maxRow  = 0;
        int                       limit   = 2000;
        int                       start   = 0;
        PageInfo<BaseConstRegion> pageRtn = baseConstRegionService.findPage(start, limit, conditon);
        while (maxRow < 50000 && pageRtn != null && (pageRtn.getList() != null && pageRtn.getList().size() > 0)) {
            for (BaseConstRegion baseConstRegion : pageRtn.getList()) {
                records.add(excelRecord(baseConstRegion));
                maxRow++;
            }
            start = start + 1;
            pageRtn = baseConstRegionService.findPage(start, limit, conditon);
        }
        // 导出数据
        _response.setContentType("application/vnd.ms-excel");
        _response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode(DateTool.formatDate(new Date(), DateTool.FULL_PATTERN), "UTF-8");
        _response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        EasyExcel.write(_response.getOutputStream(), BaseConstRegion.class).sheet(DateTool.getShortNow()).head(excelTitle()).doWrite(records);
    }

    private List<List<String>> excelTitle() {
        List<List<String>> head = new ArrayList<>();
        head.add(Lists.newArrayList("地区编码"));
        head.add(Lists.newArrayList("地区名称"));
        head.add(Lists.newArrayList("上级地区"));
        return head;
    }

    private List<String> excelRecord(BaseConstRegion constRegion) {
        List<String> rowData = Lists.newArrayList();
        rowData.add(constRegion.getRegionCode());
        rowData.add(constRegion.getRegionName());
        rowData.add(constRegion.getParentId());
        return rowData;
    }

}



